package com.itheima.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.exception.BizException;
import com.itheima.mapper.EmpExprMapper;
import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.Emp;
import com.itheima.pojo.EmpExpr;
import com.itheima.pojo.EmpLog;
import com.itheima.pojo.EmpQueryParam;
import com.itheima.pojo.LoginInfo;
import com.itheima.pojo.PageResult;
import com.itheima.service.EmpLogService;
import com.itheima.service.EmpService;
import com.itheima.utils.JwtUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 员工管理
 */
@Service
public class EmpServiceImpl implements EmpService {

    @Autowired
    private EmpMapper empMapper;

    @Autowired
    private EmpExprMapper empExprMapper;

    @Autowired
    private EmpLogService empLogService;

    /**
     * 分页查询 使用pageHelper
     *
     * @param page
     * @param pageSize
     * @return
     */
    @Override
    public PageResult<Emp> page(Integer page, Integer pageSize) {
        //1. 设置分页参数
        PageHelper.startPage(page, pageSize);
        //2. 查询数据
        // pageInfo对象，PageHelper封装了分页的结果信息
        Page<Emp> pageInfo = empMapper.list();
        //3. 返回结果
        return new PageResult<Emp>(pageInfo.getTotal(), pageInfo.getResult());
    }

    /**
     * 分页条件查询
     *
     * @param empQueryParam
     * @return
     */
    @Override
    public PageResult<Emp> pageQuery(EmpQueryParam empQueryParam) {
        //1. 设置分页参数
        PageHelper.startPage(empQueryParam.getPage(), empQueryParam.getPageSize());
        //2. 查询
        Page<Emp> pageInfo = empMapper.pageQuery(empQueryParam);
        return new PageResult<>(pageInfo.getTotal(), pageInfo.getResult());
    }

    /**
     * 新增员工
     * spring事务控制
     * rollbackFor指定哪些类型的异常需要回滚事务
     *
     * @param emp
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(Emp emp) {
        //1. 保存员工的基本信息
        // 补全其它属性
        // 默认的密码
        try {
            emp.setPassword("123456");
            emp.setCreateTime(LocalDateTime.now());
            emp.setUpdateTime(emp.getCreateTime());
            empMapper.insert(emp);
        /*if(true){
            throw new Exception("abc");
        }*/
            //int i = 1/0;
            //2. 保存员工的工作经历
            // 判断是否有工作经历
            List<EmpExpr> exprList = emp.getExprList();
            //if(exprList!=null && exprList.size() > 0)
            // 是否有经验, 避免如果类型为LinkedList，性能差，.size()遍历整链表
            if (!CollectionUtils.isEmpty(exprList)) {
                //批量保存前，设置新增的员工编号 TODO
                // 设置每个工作经历员工id
                exprList.forEach(expr -> expr.setEmpId(emp.getId()));
                // 批量保存
                empExprMapper.insertBatch(exprList);
            }
        } finally {
            empLogService.insertLog(new EmpLog(null, LocalDateTime.now(), "新增员工"));
        }
    }

    /**
     * 批量删除员工
     *
     * @param ids
     */
    @Override
    @Transactional
    public void delete(List<Integer> ids) {
        //1. 删除员工表记录
        empMapper.deleteByIds(ids);
        //2. 删除员工工作经历表记录
        empExprMapper.deleteByEmpIds(ids);
    }

    /**
     * 查询员工信息
     *
     * @param id
     * @return
     */
    /*@Override
    public Emp getInfo(Integer id) {
        //1. 查询员工基本信息
        Emp emp = empMapper.selectById(id);
        //2. 查询员工工作经历
        List<EmpExpr> exprList = empExprMapper.selectByEmpId(id);
        // 设置工作经历属性
        emp.setExprList(exprList);
        return emp;
    }*/
    @Override
    public Emp getInfo(Integer id) {
        //1. 查询员工基本信息
        Emp emp = empMapper.getById(id);
        return emp;
    }

    /**
     * 修改员工
     *
     * @param emp
     */
    @Override
    @Transactional
    public void update(Emp emp) {
        //1. 更新员工信息
        emp.setUpdateTime(LocalDateTime.now());
        empMapper.updateById(emp);
        //2. 更新员工工作经历
        // 关系的维护操作，
        // 删除旧关系，
        Integer empId = emp.getId();
        //Arrays.asList(empId)
        empExprMapper.deleteByEmpIds(List.of(empId));
        // 添加新关系
        List<EmpExpr> exprList = emp.getExprList();
        if (!CollectionUtils.isEmpty(exprList)) {
            // 设置每个工作经历 员工id
            exprList.forEach(expr -> expr.setEmpId(emp.getId()));
            // 批量保存
            empExprMapper.insertBatch(exprList);
        }
    }

    @Override
    public List<Emp> listAll() {
        List<Emp> list = empMapper.selectAll();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(e -> e.setPassword(null));
        }
        return list;
    }

    /**
     * 登录
     *
     * @param emp
     * @return
     */
    @Override
    public LoginInfo login(Emp emp) {
        // 通过用户名与密码查询员工表
        Emp empLogin = empMapper.selectByUsernameAndPassword(emp);
        // 不符合业务逻辑的代码终止，抛出自定义的异常
        if (null == empLogin) {
            throw new BizException("用户名或密码错误");
        }
        // 生成token
        Map<String,Object> claims = new HashMap<>();
        claims.put("id", empLogin.getId());
        claims.put("name", empLogin.getName());
        claims.put("username", empLogin.getUsername());
        String token = JwtUtils.generateJwt(claims);

        // 链式编程方式,不需要老是换行加;，直接通过...设置对象的属性值
        return LoginInfo.builder()
            .id(empLogin.getId())
            .name(empLogin.getName())
            .username(empLogin.getUsername())
            .token(token) // TODO
            .build();
    }

}